Skip to content

feat(lint): add nursery rule useImportsFirst#9272

Open
terror wants to merge 6 commits intobiomejs:mainfrom
terror:use-imports-first
Open

feat(lint): add nursery rule useImportsFirst#9272
terror wants to merge 6 commits intobiomejs:mainfrom
terror:use-imports-first

Conversation

@terror
Copy link

@terror terror commented Feb 28, 2026

Summary

Resolves #9265

This diff Implements the useImportsFirst lint rule, which enforces that all import statements appear before any non-import statements in a module. This corresponds to the ESLint import/first rule (see #9265). The rule iterates over the module item list and flags any JsImport that appears after a non-import item.

Test Plan

Snapshot tests in crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/:

  • invalid.js - imports after a const declaration (2 diagnostics)
  • invalid_mixed.js - imports interspersed with calls and exports (2 diagnostics)
  • valid.js - all imports grouped at the top (no diagnostics)
  • valid_with_export.js - single import before export and statement (no diagnostics)

Docs

Rule documentation is inline in the declare_lint_rule! macro and will be published automatically.

@changeset-bot
Copy link

changeset-bot bot commented Feb 28, 2026

🦋 Changeset detected

Latest commit: 70dec32

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Feb 28, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5f5245 and 2a6ad5c.

⛔ Files ignored due to path filters (4)
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_all_after.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_mixed.js.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (2)
  • crates/biome_js_analyze/src/lint/nursery/use_imports_first.rs
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_all_after.js

Walkthrough

Adds a new nursery lint rule UseImportsFirst (implements biome_analyze::Rule for Ast<JsModuleItemList) that flags import statements appearing after any non‑import module item. The rule performs a single‑pass over module items, returns offending TextRanges as signals, and produces diagnostics advising to move imports to the top. Includes UseImportsFirstOptions, rule registration metadata, a changeset, a public re‑export in biome_rule_options, and multiple test specs covering valid and invalid import orderings.

Suggested reviewers

  • ematipico
  • dyc3
  • unvalley
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a new nursery lint rule called useImportsFirst.
Description check ✅ Passed The description is well-detailed, explaining the rule's purpose, referencing the resolved issue, and documenting the test plan and implementation approach.
Linked Issues check ✅ Passed The PR fully addresses issue #9265 by implementing the useImportsFirst rule that enforces imports appear before non-import statements, matching the ESLint import/first rule requirement.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the useImportsFirst rule: rule implementation, test files, options struct, and changeset documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js (1)

1-5: Optional: add a directive-focused valid fixture.

Given the rule docs explicitly allow directives, a tiny valid_with_directive.js (e.g. "use strict"; then imports) would lock that behaviour in and guard regressions.

Based on learnings: Add tests for all code changes - lint rules need snapshot tests in tests/specs/{group}/{rule}/.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js` around
lines 1 - 5, Add a new valid fixture file (e.g., valid_with_directive.js) under
tests/specs/nursery/useImportsFirst/ that begins with a directive like "use
strict"; followed by the same import lines (import { foo } from "foo"; import {
bar } from "bar"; import { baz } from "baz"; const qux = 1;) and the same top
comment ("should not generate diagnostics") so the test suite captures that
directives are allowed by the useImportsFirst rule; ensure the file follows the
existing snapshot test pattern used in tests/specs/{group}/{rule}/ so it is
picked up by the rule tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_rule_options/src/use_imports_first.rs`:
- Line 6: Add a rustdoc comment above the public struct UseImportsFirstOptions
explaining what this options type configures (options for the
"use-imports-first" rule/assist), what each field would control (if currently
empty, state that it has no configurable fields yet and is reserved for future
settings), and include example usage or default behavior; ensure the doc uses
standard /// rustdoc format placed immediately before the declaration of
UseImportsFirstOptions.

---

Nitpick comments:
In `@crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js`:
- Around line 1-5: Add a new valid fixture file (e.g., valid_with_directive.js)
under tests/specs/nursery/useImportsFirst/ that begins with a directive like
"use strict"; followed by the same import lines (import { foo } from "foo";
import { bar } from "bar"; import { baz } from "baz"; const qux = 1;) and the
same top comment ("should not generate diagnostics") so the test suite captures
that directives are allowed by the useImportsFirst rule; ensure the file follows
the existing snapshot test pattern used in tests/specs/{group}/{rule}/ so it is
picked up by the rule tests.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 412a08d and c6d9702.

⛔ Files ignored due to path filters (7)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_mixed.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid_with_export.js.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • crates/biome_js_analyze/src/lint/nursery/use_imports_first.rs
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_mixed.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid_with_export.js
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_imports_first.rs

@siketyan
Copy link
Member

  • Restore the PR template and fill it
  • Please add a changeset

Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a couple notes

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 28, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 156 skipped benchmarks1


Comparing terror:use-imports-first (70dec32) with main (edf8bb6)

Open in CodSpeed

Footnotes

  1. 156 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@github-actions github-actions bot added the A-CLI Area: CLI label Feb 28, 2026
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📎 Implement rule to enforce all imports go at the top of the file

3 participants